
組件實作 : Demo
Card 組件通常會出現在像是購物網站的商品資訊,或是影片追劇等電影介紹中,其實只要是文字加上圖片的一個群組,都可以是一張 Card,以下我們要來實作出巴哈姆特動畫瘋【1】的畫面。

圖片來源:https://ani.gamer.com.tw/
首先,我們要製作類似上圖的 Card 組件,在最外圍用一個 container 將包住多個 card 組件。
HTML:
<div class="container">
	<!-- card 寫在這裡 -->
~~</div>~~
一個 card 組件會包含下面這些程式碼。
HTML:
<div class="card">
	<div class="card__block">
		<div class="card__img">
			<img src="https://source.unsplash.com/random/400x300?sig=1" />
		</div>
		<div class="time__block">
			<div class="time__icon"><i class="fa fa-clock-o" aria-hidden="true"></i></div>
			<div class="time__text">22:00</div>
		</div>
		<div class="card__heart"><i class="fa fa-heart-o" aria-hidden="true"></i></div>
		<div class="video__block">
			<div class="video__icon"><i class="fa fa-youtube-play" aria-hidden="true"></i></div>
			<div class="video__text">第9集</div>
		</div>
	</div>
	<div class="content">
		<div class="content__title">
			<div class="marquee__text">OVERLORD</div>
		</div>
		<div class="contrnt__item">
			<div class="content__icon"><i class="fa fa-eye" aria-hidden="true"></i></div>
			<div class="content__number">197.1萬</div>
		</div>
	</div>
</div>
顯示結果:

我們用一個 class 為 card 的 div,代表一個完整的卡片,也就是代表一部動畫的資訊,而 card 的組成如下面介紹:
card:一張卡片的所有資訊。
card__block:包含封面圖片內的所有資訊(就是不包含底下那排白底黑字的文字content)。card__img:放封面圖片。time__block:card 內部左上角關於時間的區塊。
time__icon:時鐘的 icon(時鐘圖示)。time__text:顯示時間的文字。card__heart:card 內部右上角的愛心 icon(愛心圖示)。video__block:card 內部左下角集數區塊。
video__icon:影片播放的 icon 圖示(播放圖示)。video__text:顯示集數的文字。content:card 內部最下排的白色區塊。
content__title:動畫名稱。content__item:用來包覆 icon 和 number。
content__icon:觀看次數的 icon 圖示(眼睛圖示)。content__number:顯示觀看次數的文字。如果你的架構寫好,則會出現類似上面的畫面。若是 icon 沒有正常顯示,就要加入 Font Awsome 的 CDN。
HTML:(Ver 4.7.0)
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
HTML:(愛心)
<i class="fa fa-heart-o" aria-hidden="true"></i>
HTML:(眼睛)
<i class="fa fa-eye" aria-hidden="true"></i>
HTML:(時鐘)
<i class="fa fa-clock-o" aria-hidden="true"></i>
HTML:(播放)
<i class="fa fa-youtube-play" aria-hidden="true"></i>
CSS 起手式,先讓版面置中。
CSS:
* {
	margin: 0;
	padding: 0;
	font-family: "Helvetica Neue", "Helvetica", "Arial", "PingFangTC-Light",
		"STHeitiTC-Light", "Microsoft JhengHei", "微軟正黑體", sans-serif;
}
html {
	width: 100%;
	height: 100%;
	display: flex;
	justify-content: center;
	align-items: center;
}
我們先參考手機裝置的配置。已知在手機版上,動畫瘋使用 2 欄的版面配置,然後切換到平板則是使用 3 欄的配置,最後在桌機上則是用了 5 欄的配置,我們先對於圖片內部的元素來進行排版,程式碼如下。
CSS:
.card {
	border-radius: 3px;
	font-size: 14px;
	overflow: hidden;
	box-shadow: 0 3px 4px rgba(0, 0, 0, 0.1), 0 1px 8px rgba(0, 0, 0, 0.05),
		0 2px 20px rgba(0, 0, 0, 0.1);
	cursor: pointer;
}
.card__block {
	position: relative;
	overflow: hidden;
}
.card__img {
	max-height: 95px;
	background-size: cover;
	transition: 0.5s;
}
.card__img:hover {
	transform: scale(1.5);
	transition: 0.5s;
}
.card__heart {
	position: absolute;
	top: 0;
	right: 0;
	margin: 5px;
}
.card 是 card 組件的樣式設定,我們在加入一個 box-shadow 當作是最外圍的陰影,為了要讓愛心、時間以及影片讓等內容放在圖片的裡面,我們要在把card__block的position設定為relative,當 CSS  中的position設定為absolute後,愛心、時間以及影片等圖示即可正常的排列 。
顯示結果:

接著我們要修改時間區塊相關的樣式,使用的程式碼如下。
CSS:
.time__block {
	margin: 5px;
	padding: 4px 8px;
	border-radius: 4px;
	font-size: 12px;
	color: #fff;
	background: rgba(55, 55, 55, 0.9);
	display: flex;
	position: absolute;
	top: 0;
}
.time__icon {
	margin-right: 3px;
}
顯示結果:

雖然時間圖示沒有到完全的一樣,但也是相當的接近了,我們處理完時間的區塊後,緊接著,我們要修改右上角的愛心圖示。
.fa-heart-o {
	font-size: 1rem;
	font-weight: bold;
	color: #fff;
}
這裡直接修改 Font Awsome 的預設 Class,例如,空心愛心 icon 的 Class 為 fa-heart-o。當我們改完了fa-heart-o之後,愛心的預設顏色由黑色變成白色。
顯示結果:

最後一個元素是集數區塊,我們要將它放在圖片區塊的左下角,程式碼如下。
CSS:
.video__block {
	font-weight: bold;
	margin: 5px;
	color: #fff;
	display: flex;
	align-items: center;
	position: absolute;
	bottom: 0;
}
.video__icon {
	margin-right: 3px;
}
顯示結果:

到這裡為止,我們已經將圖片區塊的元素排版完成,接下來我們想要把內容區塊做調整,首先我們要使用一個 flexbox 將文字水平排列。
CSS:
.content {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	padding: 4px 8px;
	vertical-align: middle;
}
.content__icon {
	margin: 0 3px;
	box-sizing: border-box;
}
.content__title {
	max-width: 80px;
}
顯示結果:

壞掉啦!動畫名稱的區塊文字太長了,結果被自動換到第二行,所以這個時候我們在content__title裡面加入三行程式碼,用來把過長的文字改用「點點點」來代替。
文字自動隱藏【2】這寫法非常好用,為了方便複製,我將它們寫起來:
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
overflow: hidden;:超出容器寬度時,隱藏超出範圍。white-space: nowrap;:空白與換行處理,nowrap為不自動換行。text-overflow: ellipsis;:文字溢出時,使用點點點代替。這邊要注意一點,如果你要使用自動隱藏文字,要把程式碼改寫成下面這樣。
HTML:
<div class="content__title marquee__text">來自深淵 烈日的黃金鄉</div>
因為我們要加入跑馬燈效果,就先不使用自動隱藏文字,不然跑出來結果會是點點點,如果你只是要寫靜態文字就用點點點,若是要用跑馬燈可以不用加上text-overflow: ellipsis;這句(但是另外兩行還是要加喔,不然會自動換行)。
CSS:
.content {
	display: flex;
	justify-content: space-around;
	align-items: center;
	grid-template-columns: auto auto auto;
	padding: 4px 8px;
	vertical-align: middle;
}
.content__title {
	width: 100%;
	overflow: hidden;
	white-space: nowrap;
}
.contrnt__item {
	display: grid;
	grid-template-columns: auto auto;
	gap: 5px;
	align-items: center;
	justify-content: center;
}
.content__icon {
	width: 100%;
	box-sizing: border-box;
}
.content__number {
	white-space: nowrap;
}
顯示結果:

太棒了,我們已經手刻了一個 Card 組件,在下一個章節裡,我們想要加入 RWD 排版,以及動畫名稱的區塊使用跑馬燈的效果,在這之前要先產生 5 個 分Card 組件,讓它們可以有排版的功能。
因為版面會被拉得太長所以我這邊就不先放程式碼,如果有需要的話可以直接去的 Demo 頁面找到完整的程式碼。下面我修改了文字區塊的內容 ,讓它們看起來「稍微」的不一樣。
顯示結果:

這裡的寫法不自動隱藏文字!!
還記得最外層的 Class 為 container 的 div 嗎?我們要將它當作父層,在這個 container 裡,我們只要使用 flexbox 就能輕鬆的排版,程式碼如下。
CSS:
.container {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
}
顯示結果:

水平置中對齊後⋯又壞掉啦!Flexbox 在做這種排版似乎並沒有那麼的直覺,所以我們決定改用 Grid 來排版,使用的方式如下。
CSS:
.container {
	display: grid;
	grid-template-columns: auto auto;
	gap: 12px;
	padding: 16px 12px 0;
}
顯示結果:

使用 Grid 可以很輕鬆的製作出格線整齊的版面,grid-template-columns【3】是用來分配欄數,一般我喜歡直接用 auto,幾個 auto 就會有幾欄,手機排版使用兩個 auto。另外,可以使用gap來讓每個 Card 之間都保持 12 px 的間隙,排版更佳美觀。
終於進入到了響應式排版的章節,這裡我們會針對手機、平板以及桌機的視窗大小,來做不同的版面配置,程式碼的實作如下。
CSS:
@media (min-width: 575.98px) {
	.container {
		grid-template-columns: auto auto auto;
		gap: 12px;
		padding: 16px 12px;
	}
	.card__img {
		max-height: 135px;
	}
}
@media (min-width: 1199.98px) {
	.container {
		grid-template-columns: auto auto auto auto auto;
		gap: 12px;
		padding: 16px 12px;
	}
	.card__img {
		max-height: 140px;
	}
}
575.98 px 為 3 欄的平板排版;1199.98 px 為 5 欄 的桌機排版,grid-template-columns 為 Grid 的用法,此為要平均切割幾欄的寫法,切好欄位後,再加入 gap 讓 Card 之間有適當的距離。而max-height是為了要設定成 Card 的高度與巴哈姆特動畫瘋相同,達到像素級還原的要求。
RWD 的使用會在下一篇中講解,這裡只需要先帶入 Media Queries 用法即可。
把下面這段程式碼加在 @media 的上面,我習慣將 Media Queries 寫在最底下。
CSS:
.marquee__text {
	animation: slide 7s linear infinite;
}
.marquee__text:hover {
	animation-play-state: paused;
}
@keyframes slide {
	from {
		transform: translateX(100%);
	}
	to {
		transform: translateX(-100%);
	}
}
顯示結果:

我們完整的切了一個 Card 頁面,製作的過程都類似,善用 position、Flexbox 以及 Grid,就可以做出你想要的版型。若是想要練習 Card 相關的製作,可以參考第四章節的推薦資源,裡面有各種版型可以練習,今天的實作就到這邊結束,謝謝觀看!